﻿using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Xml.Serialization;

namespace DCSoft.TemperatureChart
{
    /// <summary>
    /// 体温信息文档对象
    /// </summary>
    ///<remarks></remarks>
    [Serializable]
    [ComVisible(false)]
    public class TemperatureDocument
    {
        /// <summary>
        /// 初始化对象
        /// </summary>
        public TemperatureDocument()
        {
            
        }

        private string _Title = null;
        /// <summary>
        /// 体温单标题
        /// </summary>
        [DefaultValue( null )]
        public string Title
        {
            get { return _Title; }
            set { _Title = value; }
        }

        private string _InpatientID = null;
        /// <summary>
        /// 住院号
        /// </summary>
        [DefaultValue( null )]
        public string InpatientID
        {
            get { return _InpatientID; }
            set { _InpatientID = value; }
        }

        private string _PatientName = null;
        /// <summary>
        /// 病人姓名
        /// </summary>
        [DefaultValue( null )]
        public string PatientName
        {
            get { return _PatientName; }
            set { _PatientName = value; }
        }

        private float _PatientAge = 0f;
        /// <summary>
        /// 病人年龄
        /// </summary>
        [DefaultValue( 0f )]
        public float PatientAge
        {
            get { return _PatientAge; }
            set { _PatientAge = value; }
        }

        private string _Section = null;
        /// <summary>
        /// 病区号
        /// </summary>
        [DefaultValue( null )]
        public string Section
        {
            get { return _Section; }
            set { _Section = value; }
        }

        private string _BedID = null;
        /// <summary>
        /// 床号
        /// </summary>
        [DefaultValue( null )]
        public string BedID
        {
            get { return _BedID; }
            set { _BedID = value; }
        }

        private FooterMeasureList _FooterMeasures = new FooterMeasureList();
        /// <summary>
        /// 页脚显示的数据
        /// </summary>
        [XmlArrayItem("FooterMeasure", typeof(FooterMeasure))]
        public FooterMeasureList FooterMeasures
        {
            get
            {
                return _FooterMeasures; 
            }
            set
            {
                _FooterMeasures = value; 
            }
        }

        private MeasureList _Measures = new MeasureList();
        /// <summary>
        /// 测量数据
        /// </summary>
        [XmlArrayItem("Measure", typeof(Measure))]
        public MeasureList Measures
        {
            get
            {
                return _Measures; 
            }
            set
            {
                _Measures = value; 
            }
        }
         

        /// <summary>
        /// 更新状态
        /// </summary>
        public void UpdateState()
        {
            Measures.Sort(new MeasureComparer());
            FooterMeasures.Sort(new CMeasureComparer());
        }
         


        private int _PageIndex = 0;
        /// <summary>
        /// 从0开始计算的当前页号
        /// </summary>
        [XmlIgnore]
        [Browsable( false )]
        public int PageIndex
        {
            get
            {
                return _PageIndex;
            }
            set
            {
                _PageIndex = value;
                if (_PageIndex < 0)
                {
                    _PageIndex = 0;
                }
                if (_PageIndex >= _NumOfPages)
                {
                    _PageIndex = NumOfPages - 1 ;
                }
            }
        }

        internal int _NumOfPages = 0;
        /// <summary>
        /// 总页数
        /// </summary>
        [Browsable( false )]
        public int NumOfPages
        {
            get
            {
                return _NumOfPages;
            }
        }

        private TemperatureDocumentOptions _Options = new TemperatureDocumentOptions();
        /// <summary>
        /// 文档视图选项
        /// </summary>
        [Browsable( false )]
        [XmlIgnore]
        public TemperatureDocumentOptions Options
        {
            get
            {
                return _Options; 
            }
            set
            {
                _Options = value;
                if (_Options == null)
                {
                    _Options = new TemperatureDocumentOptions();
                }
            }
        }

        /// <summary>
        /// 更新文档的总页数
        /// </summary>
        /// <param name="maxDate">输出的数据最大日期</param>
        /// <param name="minDate">输出的数据最小日期</param>
        public void UpdateNumOfPage( out DateTime maxDate , out DateTime minDate )
        {
            // 有数据的时间区间的最大值
            maxDate = NullDate;
            // 有数据的时间区间的最小值
            minDate = NullDate;
            
            if (Measures.Count > 0)
            {
                // 计算总页数
                foreach (Measure m in Measures)
                {
                    if (maxDate == NullDate || maxDate < m.ValueDate.Date )
                    {
                        maxDate = m.ValueDate;
                    }
                    if (minDate == NullDate || minDate > m.ValueDate.Date )
                    {
                        minDate = m.ValueDate;
                    }
                }//foreach
                TimeSpan valueSpan = maxDate - minDate;
                _NumOfPages = (int)Math.Ceiling(valueSpan.Days / (double)Options.NumOfDaysInOnePage);
                if (_NumOfPages == 0)
                {
                    _NumOfPages = 1;
                }
                if (PageIndex >= NumOfPages)
                {
                    PageIndex = NumOfPages - 1;
                }
                if (PageIndex < 0)
                {
                    PageIndex = 0;
                }
            }
            else
            {
                maxDate = DateTime.Today;
                minDate = maxDate.AddDays(-Options.NumOfDaysInOnePage);
                _NumOfPages = 1;
                PageIndex = 0;
            }
        }


        public bool Load(System.IO.Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            XmlSerializer ser = new XmlSerializer(GetType());
            TemperatureDocument doc = (TemperatureDocument)ser.Deserialize(stream);
            if (doc != null)
            {
                _BedID = doc._BedID;
                _FooterMeasures = doc._FooterMeasures;
                _InpatientID = doc._InpatientID;
                _Measures = doc._Measures;
                _NumOfPages = doc._NumOfPages;
                _Options = doc._Options;
                _PageIndex = doc._PageIndex;
                _PatientAge = doc._PatientAge;
                _PatientName = doc._PatientName;
                _Section = doc._Section;
                _Title = doc._Title;
                return true;
            }
            return false;
        }

        public void Save(System.IO.Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            XmlSerializer ser = new XmlSerializer(GetType());
            ser.Serialize(stream, this);
        }

        public TemperatureDocument Clone()
        {
            TemperatureDocument doc = (TemperatureDocument)MemberwiseClone();
            if (_FooterMeasures != null)
            {
                doc._FooterMeasures = _FooterMeasures.CloneDeeply();
            }
            if (_Measures != null)
            {
                doc._Measures = _Measures.CloneDeeply();
            }
            return doc;
        }

        /// <summary>
        /// 表示空日期的字符串
        /// </summary>
        public const string NullDateString = "1980-1-1";
        /// <summary>
        /// 表示空的日期
        /// </summary>
        public static DateTime NullDate = new DateTime(1980, 1, 1);
        /// <summary>
        /// 表示空的数据
        /// </summary>
        public const float NullValue = -10000f;
        /// <summary>
        /// 是否为空日期
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static bool IsNullValue(float v)
        {
            return float.IsNaN(v) || v == NullValue;
        }
         
    }
}